package uk.ac.lkl.common.util;



import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


/**
 * <p>
 * This is a convenience class that simplifies the implementation of support for
 * firing <code>ChangeEvent</code>s.can be used by objects that fire
 * <code>ChangeEvent</code>s.
 * </p>
 * 
 * <p>
 * Consider the following example class that provides registration of
 * <code>ChangeListener</code>s and <code>ChangeEvent</code>s. An event is
 * generated when the name is set to something different (and non-null):
 * </p>
 * 
 * <pre>
 * public MyClass {
 *   
 *   private ArrayList&lt;ChangeListener&gt; listeners = new ArrayList&lt;ChangeListener&gt;();
 * 
 *   private String name;
 *   
 *   public void setName(String name) {
 *      if (name.equals(this.name))
 *        return;
 *     
 *      this.name = name;
 *      fireStateChanged();
 *   }
 *   
 *   public void addChangeListener(ChangeListener listener) {
 *      listeners.add(listener);
 *   }
 *   
 *   public void removeChangeListener(ChangeListener listener) {
 *      listeners.remove(listener);
 *   }
 *   
 *   private void fireStateChanged() {
 *      ChangeEvent e = new ChangeEvent(this);
 *      for (ChangeListener listener : listeners)
 *         listener.stateChanged(e);    
 *   }
 * 
 * }
 * </pre>
 * 
 * <p>
 * Using the support provided in <code>ChangeSupport</code>, this class can
 * be equivalently written in a simplified form as follows:
 * </p>
 * 
 * <pre>
 * public MyClass {
 *   
 *   private ChangeSupport changeSupport = new ChangeSupport(this);
 *  
 *   private String name;
 *   
 *   public void setName(String name) {
 *      if (name.equals(this.name))
 *        return;
 *     
 *      this.name = name;
 *      changeSupport.fireStateChanged();
 *   }
 *   
 *   public void addChangeListener(ChangeListener listener) {
 *      changeSupport.addListener(listener);
 *   }
 *   
 *   public void removeChangeListener(ChangeListener listener) {
 *      changeSupport.removeListener(listener);
 *   }
 * 
 * }
 * </pre>
 * 
 *
 * <p>
 * In this way, we have used <code>ChangeSupport</code> as a class member and
 * delegated listener registration and event firing to it, simplifying our code.
 * </p>
 * 
 * @author Richard Siddons-Corby
 * @version $Revision: 590 $
 * @version $Date: 2008-02-13 23:09:44 +0000 (Wed, 13 Feb 2008) $
 * @see EventSupport
 * 
 */
public class ChangeSupport extends EventSupport<ChangeListener> {

    private final ChangeEvent event;


    /**
     * Construct the underlying <code>EventSupport</code> with the given event
     * source for the <code>ChangeListener</code> class type.
     * <p>
     * 
     * @param source
     *            the event source
     */
    public ChangeSupport(Object source) {
        super(source);
        event = new ChangeEvent(source);
    }


    @Override
    protected Class<ChangeListener> getListenerClass() {
        return ChangeListener.class;
    }


    /**
     * Run each <code>ChangeListener</code>'s <code>stateChanged</code>
     * method with a default <code>ChangeEvent</code> which has the same
     * source as that passed to the constructor.
     */
    public void fireStateChanged() {
        fireStateChanged(event);
    }


    /**
     * Run each <code>ChangeListener</code>'s <code>stateChanged</code>
     * method with a given <code>ChangeEvent</code>.
     * <p>
     * 
     * @param e
     *            the event object to send
     */
    public void fireStateChanged(ChangeEvent e) {
        ChangeListener [] listeners = (ChangeListener []) getListeners();
        for (int i = 0; i < listeners.length; i++) {
            listeners[i].stateChanged(e);
        }
    }
}